<template>
  <div id="drawArea">
    <div class="set-s">
      <!-- <el-dialog :title="titleCon" v-model="isUseDialog" draggable :close-on-click-modal="false" :fullscreen="true"
        :before-close="handleClose" :destroy-on-close="true"> -->
      <!--   <div v-if="showOverlay" class="overlay">
          <div class="hint-s">
            <h4>操作提示</h4>
            <p>在使用绘图工具前，请先进行区域绘制并保存绘制的区域。</p>
            <footer>将在 <span style="color: #FFDE0A; font-size: 14px;">{{ countDownSec }}S</span> 后自动关闭</footer>
          </div>
        </div> -->

      <!-- <div class="outer-sphere"> -->
      <!-- <div class="fun-btn"> -->
      <!-- <el-tooltip class="box-item" effect="dark" content="在使用绘图工具前，请先进行区域绘制并保存绘制的区域。" placement="right-start">
              <el-button style="font-weight: bold;padding: 0;margin-bottom: 15px;" text type="danger">操作提示<el-icon
                  class="el-icon--right">
                  <QuestionFilled />
                </el-icon></el-button>
            </el-tooltip> -->
      <!-- <el-button class="end-draw" @click="saveCurrentRegion">保存区域绘制</el-button>
            <el-button class="end-draw" @click="clearDraw">清除全部绘制</el-button>
            <el-button v-if="isMapping" class="end-draw" @click="returnStep">返回上一步</el-button>
            <el-button v-if="clearCurrent" class="end-draw" @click="clearCurrentHandle">清除当前区域</el-button> -->
      <!-- </div> -->
      <!-- <div class="out-box" ref="outBox"> -->
      <!-- <ul class="color-s"> -->
      <!-- <li v-for="(item, index) in setColor" :key="index"><span :style="{ backgroundColor: item.color }"></span>{{
                item.title }}</li>
            </ul> -->
      <div id="konvaContainer" ref="konvaContainer"></div>
      <!-- </div> -->
      <!-- </div> -->
      <!-- <template #footer>
          <el-button @click="cancelUseClick">取消</el-button>
          <el-button type="primary" :loading="repeatDis" :disabled="repeatDis" @click="submitForm">提交</el-button>
        </template> -->
      <!-- </el-dialog> -->
    </div>
    <!-- <DialogHt :isAnewConfig="isAnewConfig" :dialogVisible="dialogVisible" @cancelHtClick="cancelHtClick"
      @confirmHtClick="confirmHtClick" /> -->
  </div>
</template>
<script lang="ts">
import { defineComponent, ref, computed, watch, Ref, nextTick, provide, toRaw, onMounted } from 'vue';
import { ElButton, ElDialog, ElMessage } from 'element-plus';
import DialogHt from './dialog-ht.vue';
import { SMSDCRiskPartitionDrawAreaChart } from '/@/api/centerControl/sms';
import Konva from 'konva';
// import imageBj from '../images/svg.png';
import imageBj from '/@/assets/jsc_images/icon24.png';
import { deepClone } from '/@/utils/exportToExcel';
declare global {
  interface Window {
    saveImage: () => void;
    copyImageURL: () => void;
    openImageInNewTab: () => void;
    clearNewTab: () => void;
  }
}
export default defineComponent({
  name: 'drawArea',
  components: {
    DialogHt,
  },
  props: {
    isUseDialog: {
      type: Boolean,
      default: false,
    },
    drawInfo: {
      type: String,
      default: ''
    },
    coordinatesArr: {
      type: Array,
      default: []
    }
  },
  setup(props, ctx) {
    let currentStatus = false;
    const titleCon = ref();
    const repeatDis = ref(false);
    const dialogVisible = ref(false);
    // const container = ref('konvaContainer'); // 获取 DOM 容器
    const konvaContainer: Ref = ref(null);
    const outBox: Ref = ref(null);
    const drawnRegions: any = ref([]); // 用于保存绘制区域的数组
    let uploadAreaArr: any = []; // 用户通过拖拽圆点更新区域的数据
    provide('dialogVisible', dialogVisible);
    const definitionColor = ref([
      { title: '受控', color: 'rgba(64, 158, 255, 0.5)', riskLevel: true },
      { title: '非受控', color: 'rgba(255, 222, 10, 0.5)', riskLevel: false },
    ]);
    const setColor = ref([
      { title: '受控', color: '#409EFF' },
      { title: '非受控', color: '#FFDE0A' },
    ]);
    const showOverlay = ref(true); // 设置倒计时蒙层
    const isMapping = ref(false); // 是否可执行测绘路径操作
    const countDownSec = ref(5); // 倒计时

    const bubbleDataArray: any = ref([]); // 保存气泡数据信息
    let userPoints: any = []; // 存储用户点击的坐标点
    let layer: any = new Konva.Layer(); // 创建 Konva 层
    let bubbleLayer = new Konva.Layer(); // 创建气泡层
    let backgroundLayer = new Konva.Layer(); // 创建背景图层
    let backgroundImage: any; // 放置背景图
    let GetBool = false;
    let stage: any;
    let pos: any;
    let bubbleText: any;
    let getX: any = '';
    let getY: any = '';
    let rightCo: any = ''; // 右键坐标
    let stageWidth = 0;
    let stageHeight = 0;
    let bubbleGroup: any;
    let bubbleGroupArr: any = [];
    let globalColor: any = ''; // 设置全局颜色
    let isSubmit = true;
    let initialBubble: any = []; // 初始气泡
    let initialDrawn: any = []; // 初始区域
    let isSetColor = false;
    let isEdit = false;
    const clearCurrent = ref(false);
    let clearInx: any;
    let clearArea: Function = () => { };
    const isAnewConfig = ref(true);

    /*** 清除当前绘制 */
    const clearCurrentHandle = () => {
      if (uploadAreaArr.length !== 0) uploadAreaArr = [];
      if (userPoints.length !== 0) userPoints = [];
      layer.find('.clear-draggable').forEach((shape: any) => shape.remove()); // 清除所有区域
      layer.draw();
      if (clearInx !== undefined) {
        currentStatus = true;
        clearArea();
      }
      clearCurrent.value = false;
      currentStatus = true;
      isMapping.value = false;
    }

    // isPointInsidePolygon 检查一个点是否在多边形内的辅助函数
    const isPointInsidePolygon = (point: any, polygon: any) => {
      const x = point.x;
      const y = point.y;

      let inside = false;
      for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
        const xi = polygon[i].x;
        const yi = polygon[i].y;
        const xj = polygon[j].x;
        const yj = polygon[j].y;

        const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;

        if (intersect) {
          inside = !inside;
        }
      }
      return inside;
    };

    /*** 更新气泡文本内容 */
    const updateBubbleText = (bubbleId: any, newText: string, num: number) => {
      const bubbleData = bubbleDataArray.value.find((data: any) => data.id === bubbleId);
      if (bubbleData) {
        bubbleData.text = newText;
        // 将文本内容更新到对应气泡内
        let findArr = bubbleDataArray.value.filter((item: any) => { return item.id === bubbleId });
        if (findArr.length !== 0) {
          bubbleText.text(newText);
          // 清除 bubbleLayer 中的所有内容
          bubbleLayer.removeChildren();
          anewDrawBubble();
          bubbleLayer.draw();
        }
      }
    };

    /*** 重新绘制气泡 */
    const anewDrawBubble = () => {
      if (bubbleDataArray.value.length !== 0) {
        bubbleGroupArr = [];
        bubbleDataArray.value.forEach((bubbleData: any, inxVal: number) => {
          // 创建气泡的背景
          const bubbleBackground = new Konva.Rect({
            width: 150, // 设置气泡的宽度
            height: 50, // 设置气泡的高度
            fill: 'lightblue', // 设置气泡的背景颜色
            cornerRadius: 4, // 设置气泡的圆角半径
          });

          // 创建一个 Group 来存放气泡的内容
          bubbleGroup = new Konva.Group({
            x: bubbleData.x, // 设置气泡的 x 坐标
            y: bubbleData.y, // 设置气泡的 y 坐标
            draggable: drawnRegions.value[inxVal].isMasterRecord || drawnRegions.value[inxVal].isMasterRecord === undefined ? true : false, // 设置 Group 可拖拽
            // 可以更改 Group 的锚点（origin）来改变其相对位置的参考点。默认情况下，Group 的锚点是左上角 (0, 0)。你可以将锚点设置为左下角 (0, 1)，这样 Group 的位置将相对于其左下角定位。
            offset: {
              x: bubbleBackground.width() / 2,
              y: bubbleBackground.height() + 8, // 假设气泡的高度为50
            }
          });

          // 创建气泡中的文本
          bubbleText = new Konva.Text({
            text: bubbleData.text, // 设置文本内容
            fontSize: 14, // 设置字体大小
            fill: 'black', // 设置字体颜色
            align: 'center', // 设置文本对齐方式
            width: 150, // 设置文本区域的宽度
            padding: 10, // 设置文本内边距
            name: 'bubble-text', // 设置文本名称
            index: bubbleData.index, // 气泡的标识（新增的时候不需要）
          });

          // 计算三角形的位置
          const triangleX = bubbleBackground.width() / 2;
          const triangleY = bubbleBackground.height();

          // 创建三角形
          const triangle = new Konva.RegularPolygon({
            sides: 3, // 三角形的边数
            radius: 10, // 三角形的半径
            fill: 'lightblue', // 三角形的填充颜色，与气泡的背景颜色一致
            x: triangleX, // 使三角形位于气泡的中心
            y: triangleY, // 使三角形位于气泡的下方
            rotation: 180, // 旋转三角形使其倒置
          });

          // 将背景和文本添加到 Group 中
          bubbleGroup.add(bubbleBackground);
          bubbleGroup.add(bubbleText);
          bubbleGroup.add(triangle);

          let setObj: any = {};
          setObj.bubbleGroupDra = bubbleGroup;
          setObj.index = bubbleData.index;
          setObj.id = bubbleData.id;
          bubbleGroupArr.push(setObj);

          // 将 Group 添加到舞台
          bubbleLayer.add(bubbleGroup);
          // 将图层添加到舞台
          stage.add(bubbleLayer);
        });
      }
    };

    /*** 创建气泡 */
    const creatGroup = async (x: any, y: any, txt?: any) => {
      // 检查指针是否在绘制的区域内
      let clickedRegionIndex: any = '';
      if (!isAnewConfig.value) {
        let len = drawnRegions.value.length - 1;
        if (x === drawnRegions.value[len].points[0].x && y === drawnRegions.value[len].points[0].y) {
          clickedRegionIndex = len;
        } else {
          clickedRegionIndex = drawnRegions.value.findIndex((region: any) => {
            return isPointInsidePolygon(rightCo, region.points);
          });
        }
      }
      if (clickedRegionIndex !== -1 || isAnewConfig.value) {
        let bubbleIndex: any = '';
        let clickedRegionData: any = {};
        if (!isAnewConfig.value) {
          clickedRegionData = drawnRegions.value[clickedRegionIndex];
          bubbleIndex = bubbleDataArray.value.findIndex((data: any) => data.index === clickedRegionData.index);
        } else {
          bubbleIndex = -1;
          clickedRegionData.index = drawnRegions.value.length;
        }

        if (bubbleIndex !== -1) {
          updateBubbleText(bubbleDataArray.value[bubbleIndex].id, txt, bubbleIndex);
        } else {
          // 创建气泡的背景
          const bubbleBackground = new Konva.Rect({
            width: 150, // 设置气泡的宽度
            height: 50, // 设置气泡的高度
            fill: 'lightblue', // 设置气泡的背景颜色
            cornerRadius: 4, // 设置气泡的圆角半径
          });

          // 创建一个 Group 来存放气泡的内容
          bubbleGroup = new Konva.Group({
            x: x, // 设置气泡的 x 坐标
            y: y, // 设置气泡的 y 坐标
            draggable: true, // 设置 Group 可拖拽
            // 可以更改 Group 的锚点（origin）来改变其相对位置的参考点。默认情况下，Group 的锚点是左上角 (0, 0)。你可以将锚点设置为左下角 (0, 1)，这样 Group 的位置将相对于其左下角定位。
            offset: {
              x: bubbleBackground.width() / 2,
              y: bubbleBackground.height() + 8, // 假设气泡的高度为50
            }
          });

          // 创建气泡中的文本
          bubbleText = new Konva.Text({
            text: txt, // 设置文本内容
            fontSize: 14, // 设置字体大小
            fill: 'black', // 设置字体颜色
            align: 'center', // 设置文本对齐方式
            width: 150, // 设置文本区域的宽度
            padding: 10, // 设置文本内边距
            name: 'bubble-text', // 设置文本名称
            index: clickedRegionData.index,
          });

          // 计算三角形的位置
          const triangleX = bubbleBackground.width() / 2;
          const triangleY = bubbleBackground.height();

          // 创建三角形
          const triangle = new Konva.RegularPolygon({
            sides: 3, // 三角形的边数
            radius: 10, // 三角形的半径
            fill: 'lightblue', // 三角形的填充颜色，与气泡的背景颜色一致
            x: triangleX, // 使三角形位于气泡的中心
            y: triangleY, // 使三角形位于气泡的下方
            rotation: 180, // 旋转三角形使其倒置
          });

          // 将背景和文本添加到 Group 中
          bubbleGroup.add(bubbleBackground);
          bubbleGroup.add(bubbleText);
          bubbleGroup.add(triangle);

          // 保存气泡数据
          const bubbleData = {
            id: bubbleGroup._id, // 气泡的唯一标识
            x: Math.min(x),
            y: Math.min(y),
            text: txt,
            group: bubbleGroup,
            index: clickedRegionData.index,
          };

          bubbleDataArray.value.push(bubbleData);
          // bubbleGroupArr = [];
          let setObj: any = {};
          setObj.bubbleGroupDra = bubbleGroup;
          setObj.id = clickedRegionData.id;
          setObj.index = clickedRegionData.index;
          bubbleGroupArr.push(setObj);

          bubbleGroupArr.forEach((item: any, inxVal: number) => {
            // 在bubbleGroup上拖动的事件监听器
            const { bubbleGroupDra } = bubbleGroupArr[inxVal];
            bubbleGroupDra.on('dragmove', () => {
              const updatedCoordinates = {
                x: bubbleGroupDra.x(),
                y: bubbleGroupDra.y(),
              };
              // 在数组中查找被拖动的气泡索引
              const filteredData = bubbleDataArray.value.filter((data: any) => data.index === item.index);
              if (filteredData) {
                filteredData[0].x = updatedCoordinates.x;
                filteredData[0].y = updatedCoordinates.y;
                bubbleDataArray.value[item.index] = filteredData[0];
              }
            });
          });

          // 将 Group 添加到舞台
          bubbleLayer.add(bubbleGroup);
          // 将图层添加到舞台
          stage.add(bubbleLayer);
        }
      } else {
        ElMessage({
          type: 'error',
          message: '提示，未找到区域位置，无法配置气泡。',
          duration: 5000
        })
      }
    };

    /*** 移动气泡 */
    const bubbleMove = () => {
      if (bubbleGroup && bubbleDataArray.value.length !== 0) {
        bubbleGroupArr.forEach((item: any, inxVal: number) => {
          // 在bubbleGroup上拖动的事件监听器
          const { bubbleGroupDra } = bubbleGroupArr[inxVal];
          bubbleGroupDra.on('dragmove', () => {
            const updatedCoordinates = {
              x: bubbleGroupDra.x(),
              y: bubbleGroupDra.y(),
            };

            // 在数组中查找被拖动的气泡索引
            let filteredData: any;
            filteredData = bubbleDataArray.value.filter((data: any) => data.id === item.id);
            if (filteredData.length !== 0 && bubbleDataArray.value[inxVal].id === item.id) {
              filteredData[0].x = updatedCoordinates.x;
              filteredData[0].y = updatedCoordinates.y;
              filteredData[0].group.attrs.x = updatedCoordinates.x;
              filteredData[0].group.attrs.y = updatedCoordinates.y;
              bubbleDataArray.value[item.inxVal] = filteredData[0];
            }
          });
        });
      }
    }

    /*** handleClose 关闭按钮点击事件 */
    const handleClose = () => {
      cancelUseClick();
    }

    /*** cancelUseClick 取消事件 */
    const cancelUseClick = () => {
      clearDataFun();
      ctx.emit('cancelDrawClick')
    }

    /*** 清除初始化数据 */
    const clearDataFun = () => {
      repeatDis.value = false;
      showOverlay.value = false;
      currentStatus = true;
      bubbleDataArray.value = [];
      drawnRegions.value = [];
      userPoints = [];
      getX = '';
      getY = '';
      rightCo = '';
      stageWidth = 0;
      stageHeight = 0;
      uploadAreaArr = [];
      bubbleGroupArr = [];
      globalColor = '';
      countDownSec.value = 5;
      isSubmit = true;
      isSetColor = false;
      isEdit = false;
      isAnewConfig.value = true;
      initialBubble = []; // 初始气泡
      initialDrawn = []; // 初始区域
    }

    /*** 提交事件 */
    const submitForm = async () => {
      if (!isSubmit) {
        ElMessage({
          type: 'error',
          message: '您有绘制的区域未保存，请先保存绘制的区域',
          duration: 5000,
        });
        return;
      }
      if (drawnRegions.value.length !== bubbleDataArray.value.length) {
        ElMessage({
          type: 'error',
          message: '您有区域未配置气泡内容，请配置',
          duration: 5000,
        });
        return;
      }

      let submitDrawn: any = [];
      let submitBubble: any = [];
      drawnRegions.value.map((item: any, inx: any) => {
        if (item.isMasterRecord === true || item.isMasterRecord === undefined) {
          submitDrawn.push(item);
          submitBubble.push(bubbleDataArray.value[inx]);
        }
      });
      if (submitDrawn.length === 0 && submitBubble.length === 0) {
        ElMessage({
          type: 'error',
          message: '您尚未绘制 “当前分区” 的区域，请绘制区域并保存',
          duration: 5000,
        });
        return;
      }
      let bubbleArr: any = [];
      let drawnArr: any = [];
      if (submitBubble.length !== 0) {
        submitBubble.map((i: any) => {
          let setObj: any = {};
          let groupObj: any = {};
          groupObj.attrs = {
            x: (Math.round(i.x) / stage.width()) * stage.scaleX(),
            y: (Math.round(i.y) / stage.height()) * stage.scaleY(),
            draggable: i.group.attrs.draggable,
          };
          groupObj.children = i.group.children;
          groupObj.className = i.group.className;
          setObj.group = groupObj;
          setObj.id = i.id;
          setObj.index = i.index;
          setObj.text = i.text;
          setObj.x = (Math.round(i.x) / stage.width()) * stage.scaleX();
          setObj.y = (Math.round(i.y) / stage.height()) * stage.scaleY();
          bubbleArr.push(setObj);
        });
      }

      if (submitDrawn.length !== 0) {
        submitDrawn.map((i: any) => {
          let setObj: any = {};
          setObj.color = i.color;
          setObj.index = i.index;
          let pointsArr: any = [];
          for (let j = 0; j < i.points.length; j++) {
            let pointsObj: any = {};
            pointsObj.x = (Math.round(i.points[j].x) / stage.width()) * stage.scaleX();
            pointsObj.y = (Math.round(i.points[j].y) / stage.height()) * stage.scaleY();
            pointsArr.push(pointsObj);
          }
          setObj.points = pointsArr;
          drawnArr.push(setObj);
        });
      }

      let param: any = {};
      let setObj: any = {};
      setObj.bubbleDataArray = bubbleArr;
      setObj.drawnRegions = drawnArr;
      param.id = JSON.parse(props.drawInfo).id;
      param.v_Coordinates = JSON.stringify(setObj);
      repeatDis.value = true;
      try {
        let res: any = await SMSDCRiskPartitionDrawAreaChart(param);
        if (res.success) {
          repeatDis.value = false;
          clearDataFun();
          ctx.emit('updateData');
          ctx.emit('controlDrawClick');
        } else {
          clearDataFun();
          repeatDis.value = false;
        }
      } catch (error) {
        repeatDis.value = false;
        clearDataFun();
      }
    }

    /*** 绘制坐标点 */
    const repaintCoord = () => {
      let getData = props.coordinatesArr;
      let bubbleArrList: any = [];
      let drawnArrList: any = [];

      let item = JSON.parse(props.drawInfo);
      // 设置全局颜色
      let riskVal = definitionColor.value.filter((val: any) => { return item.isControlled === val.riskLevel });
      globalColor = riskVal[0].color;

      if (getData.length !== 0) {
        getData.map((i: any) => {
          let val = JSON.parse(i.v_Coordinates);
          if (i.id === item.id) {
            // 找到主记录的数据
            val.drawnRegions.forEach((element: any) => {
              element.isMasterRecord = true;
            });
          } else {
            val.drawnRegions.forEach((element: any) => {
              element.isMasterRecord = false;
            });
          }
          bubbleArrList = [...bubbleArrList, ...val.bubbleDataArray];
          drawnArrList = [...drawnArrList, ...val.drawnRegions];
        });
      }

      let bubbleArr = bubbleArrList;
      let drawnArr = drawnArrList;

      let setBubbleArr: any = [];
      let setDrawnArr: any = [];

      if (bubbleArr.length !== 0) {
        bubbleArr.map((i: any) => {
          let setBubbleObj: any = {};
          let groupObj: any = {};
          groupObj.attrs = {
            x: Math.round(i.group.attrs.x * stage.width()),
            y: Math.round(i.group.attrs.y * stage.height()),
            draggable: i.group.attrs.draggable,
          };
          groupObj.children = i.group.children;
          groupObj.className = i.group.className;
          setBubbleObj.group = groupObj;
          setBubbleObj.id = i.id;
          setBubbleObj.index = i.index;
          setBubbleObj.text = i.text;
          setBubbleObj.x = Math.round(i.x * stage.width());
          setBubbleObj.y = Math.round(i.y * stage.height());
          setBubbleArr.push(setBubbleObj);
        });
      }
      if (drawnArr.length !== 0) {
        drawnArr.map((i: any) => {
          let setDrawnObj: any = {};
          // setDrawnObj.color = riskVal[0].color;
          setDrawnObj.isMasterRecord = i.isMasterRecord;
          setDrawnObj.color = i.color;
          setDrawnObj.index = i.index;
          let pointsArr: any = [];
          for (let j = 0; j < i.points.length; j++) {
            let setObj: any = {};
            setObj.x = Math.round(i.points[j].x * stage.width());
            setObj.y = Math.round(i.points[j].y * stage.height());
            pointsArr.push(setObj);
          }
          setDrawnObj.points = pointsArr;
          setDrawnArr.push(setDrawnObj);
        });
      }
      bubbleDataArray.value = setBubbleArr;
      drawnRegions.value = setDrawnArr;
      setDrawnArr.map((item: any, inx: any) => {
        if (item.isMasterRecord === false) {
          initialBubble.push(JSON.parse(JSON.stringify(setBubbleArr[inx])));
          initialDrawn.push(JSON.parse(JSON.stringify(item)));
        }
      });
      drawAllRegions(); // 在画布中绘制区域
      bubbleMove(); // 移动气泡
    }

    /*** 监听isUseDialog的变化 */
    watch(() => props.isUseDialog, (newVal) => {
      if (newVal) {
        // 重置的数据
        repeatDis.value = false;
        showOverlay.value = true;
        currentStatus = true;
        bubbleDataArray.value = [];
        drawnRegions.value = [];
        userPoints = [];
        getX = '';
        getY = '';
        rightCo = '';
        stageWidth = 0;
        stageHeight = 0;
        uploadAreaArr = [];
        bubbleGroupArr = [];
        globalColor = '';
        countDownSec.value = 5;
        isSubmit = true;
        isSetColor = false;
        isEdit = false;
        clearCurrent.value = false;
        isAnewConfig.value = true;
        initialBubble = []; // 初始气泡
        initialDrawn = []; // 初始区域
        countDownFun();
        let setTime = setInterval(async () => {
          if (konvaContainer.value) {
            clearDraw();
            await customFun();
            titleCon.value = '绘制区域';
            clearInterval(setTime);
          }
        }, 20);
      }
    })

    /*** 倒计时函数 */
    const countDownFun = () => {
      let setTime = setInterval(() => {
        if (countDownSec.value === 0) {
          showOverlay.value = false;
          clearInterval(setTime);
        } else {
          countDownSec.value = countDownSec.value - 1;
        }
      }, 1000);
    }

    /*** 自定义函数 */
    const customFun = () => {
      nextTick(() => {
        const Timers = setInterval(() => {
          if (konvaContainer.value) {
            stageWidth = konvaContainer.value.clientWidth;
            stageHeight = konvaContainer.value.clientHeight;
            GetBool = true;
            StageFun();
            clearInterval(Timers);
          }
        }, 10);
      });
    }

    /*** isUseDialog 响应弹窗的关闭  */
    const isUseDialog = computed(() => {
      return props.isUseDialog
    })

    /*** 右键功能弹出窗口取消事件 */
    const cancelHtClick = () => {
      if (isAnewConfig.value) {
        currentStatus = false;
        isSetColor = true;
      }
      dialogVisible.value = false;
    }

    /*** 右键功能弹出窗口提交事件 */
    const confirmHtClick = async (info: any) => {
      if (info) {
        await creatGroup(getX, getY, info);
        if (isAnewConfig.value) {
          drawnRegions.value.push({
            points: [...userPoints],
            color: globalColor, // 设置每个区域的颜色
            index: drawnRegions.value.length, // 分配区域的索引
          });
          // 清空当前用户绘制的坐标
          userPoints = [];
          // 清除重绘区域
          uploadAreaArr = [];
          // 绘制保存的所有区域
          drawAllRegions();
          getX = '';
          getY = '';
        }
        bubbleMove(); // 移动气泡
        dialogVisible.value = false;
      } else {
        ElMessage({
          type: 'error',
          message: '提示，请先输入区域标题。',
          duration: 5000
        })
      }
    }

    /*** clearDraw 清除全部绘制 */
    const clearDraw = () => {
      drawnRegions.value = []; // 用于保存绘制区域的数组
      userPoints = []; // 存储用户点击的坐标点
      layer.removeChildren(); // 清空舞台上的所有图像
      bubbleLayer.removeChildren(); // 清除气泡内容层
      // 重新添加 customShape
      layer.add(customShape);
      // 清除气泡数组
      bubbleDataArray.value = [];
      // 清除所有区域的时候非主记录区域不能清除
      if (initialBubble.length !== 0 && initialDrawn.length !== 0) {
        // 遍历历史中的所有区域，并绘制
        initialDrawn.map((item: any, inx: any) => {
          if (item.isMasterRecord !== undefined) {
            drawnRegions.value.push(item);
            if (initialBubble[inx]) bubbleDataArray.value.push(initialBubble[inx]);
          }
        });
        drawnRegions.value.forEach((points: any) => {
          // 创建 Konva 路径
          drawRegion(points);
        });
        // 重新绘制气泡
        anewDrawBubble();
      }
      // 更新层
      layer.draw();
      isEdit = false;
      isMapping.value = false;
    };

    /*** returnStep 返回上一步 */
    const returnStep = () => {
      if (userPoints.length !== 0) {
        layer.removeChildren(); // 清空舞台上的所有图像
        bubbleLayer.removeChildren(); // 清除气泡内容层
        userPoints.pop();
        // 重新添加 customShape
        layer.add(customShape);
        dragFun(true);
        // 重新绘制路径
        anewDraw();
        // 重新绘制气泡
        anewDrawBubble();
        // 更新层
        layer.draw();
        if (userPoints.length === 0) {
          isMapping.value = false;
          currentStatus = true;
          isSubmit = true;
          clearCurrent.value = false;
        }
      } else {
        isMapping.value = false;
        currentStatus = true;
        isSubmit = true;
        ElMessage({
          type: 'error',
          message: '提示，当前无可撤回的路径。',
          duration: 5000
        })
      }
    };

    /** 绘制单个区域 */
    const drawRegion = (region: any) => {
      const { points, color } = region;
      if (Array.isArray(points)) {
        // 创建 Konva 路径
        const path = new Konva.Path({
          data: getPathData(points),
          fill: color,
          stroke: 'rgba(255,255,255,0.3)',
          strokeWidth: 0.5,
          name: 'current-region-paths',
        });

        // 将路径添加到层
        layer.add(path);
      }
    };

    /*** anewDraw 重新绘制自定图形 */
    const anewDraw = () => {
      if (drawnRegions.value.length !== 0) {
        drawnRegions.value.forEach((points: any) => {
          // 创建 Konva 路径
          drawRegion(points);
        });
      }
    };

    // 创建 Konva 自定义图形
    const customShape = new Konva.Shape({
      sceneFunc: function (context) {
        // 使用 Konva.Context 绘制自定义图形
        // 如果有用户点击的坐标点，绘制多边形
        if (userPoints.length > 0) {
          context.beginPath();
          context.moveTo(userPoints[0].x, userPoints[0].y);

          for (let i = 1; i < userPoints.length; i++) {
            context.lineTo(userPoints[i].x, userPoints[i].y);
          }

          context.closePath();

          // 设置填充颜色
          context.fillStyle = globalColor;
          context.fill();

          // 设置描边颜色和宽度
          context.strokeStyle = 'rgba(255, 255, 255, 0.3)';
          context.lineWidth = 0.5;
          context.stroke();
        }
      },
    });

    /*** 在画布中绘制保存的所有区域 */
    const drawAllRegions = () => {
      // 清空舞台上的所有图形
      layer.removeChildren();
      bubbleLayer.removeChildren(); // 清除气泡内容层

      // 重新添加 customShape如果不重新添加会出现重新绘制区域的时候能获取到坐标点但是无法重新绘制的区域无法显示在舞台上
      // 原因是做了清空舞台上的所有图形这一步操作
      layer.add(customShape);
      // 遍历历史中的所有区域，并绘制
      drawnRegions.value.forEach((points: any) => {
        // 创建 Konva 路径
        drawRegion(points);
      });
      // 重新绘制气泡
      anewDrawBubble();
      // 更新层
      layer.draw();
    };

    /*** 圆点拖拽处理函数 */
    const dragFun = (isClear: Boolean) => {
      // 移除当前区域的所有路径
      let len = userPoints.length - 1;
      userPoints.forEach((point: any, pointIndex: any) => {
        if (len === pointIndex || isClear) {
          const circle: any = new Konva.Circle({
            x: point.x,
            y: point.y,
            radius: 6,
            fill: 'rgba(255,255,255,0.5)',
            stroke: 'rgba(255,0,0,0.3)',
            strokeWidth: 0.7,
            draggable: true,  // 允许拖拽
            name: 'clear-draggable',
          });

          // 监听拖动事件
          circle.on('dragmove', () => {
            // 更新被拖动点的坐标
            const updatedCoordinates = {
              x: circle.x(),
              y: circle.y(),
            };
            // 更新区域坐标
            userPoints[pointIndex] = updatedCoordinates;
            // 重新绘制当前区域
            const path = new Konva.Path({
              data: getPathData(userPoints),
              // fill: globalColor,
              // stroke: 'rgba(255, 255, 255, 0.3)',
              strokeWidth: 0.5,
              name: 'current-region-path',
            });

            // 将路径添加到层
            layer.add(path);

            // 更新层
            layer.draw();
          });

          // 鼠标移入圆点创建提示元素
          circle.on('mouseover', () => {
            const stage = circle.getStage();
            if (stage) {
              stage.container().style.cursor = 'pointer';

              // 创建工具提示元素
              const tooltip = document.createElement('div');
              tooltip.className = 'tooltip';
              tooltip.textContent = '可拖动';
              tooltip.style.color = '#262727'; // 设置提示字体的颜色
              tooltip.style.fontWeight = '600'; // 设置提示字体的粗细
              tooltip.style.fontSize = '16px'; // 设置提示字体的大小

              // 将工具提示放在圆旁边
              const containerRect = stage.container().getBoundingClientRect();
              const circlePosition = circle.getAbsolutePosition();
              tooltip.style.position = 'absolute';
              tooltip.style.top = `${circlePosition.y + containerRect.top - 60}px`;
              tooltip.style.left = `${circlePosition.x + containerRect.left - 140}px`;

              // 将工具提示追加到鼠标旁边
              stage.container().appendChild(tooltip);

              // 设置一个标志来跟踪工具提示是否显示
              circle.tooltipDisplayed = true;
            }
          });

          // 鼠标移除圆点清除创建的元素
          circle.on('mouseout', () => {
            const stage = circle.getStage();
            if (stage) {
              stage.container().style.cursor = 'crosshair';
              if (circle.tooltipDisplayed) {
                const tooltip = stage.container().querySelector('.tooltip');
                if (tooltip) {
                  tooltip.remove();
                  circle.tooltipDisplayed = false;
                }
              }
            }
          });
          // 将拖拽点添加到层
          layer.add(circle);
        }
      });
    }

    /*** 在点击保存按钮时，将当前用户绘制的区域添加到 drawnRegions 数组中 */
    const saveCurrentRegion = () => {
      if (uploadAreaArr.length !== 0) userPoints = uploadAreaArr;
      if (!currentStatus) {
        // 如果有用户绘制的坐标点，将最后一个点和第一个点连接
        if (userPoints.length > 2) {
          // 将用户绘制的坐标点添加到数组
          if (isSetColor) {
            // userPoints.push({ x: userPoints[0].x, y: userPoints[0].y });
            getX = userPoints[0].x;
            getY = userPoints[0].y;
            dialogVisible.value = true;
          }
          if (isEdit) {
            // 清空当前用户绘制的坐标
            userPoints = [];
            // 清除重绘区域
            uploadAreaArr = [];
            // 绘制保存的所有区域
            drawAllRegions();
          }
          // 清除 bubbleLayer 中的所有内容
          bubbleMove(); // 移动气泡
          bubbleLayer.removeChildren(); // 清除所有气泡
          anewDrawBubble(); // 重新渲染气泡
        } else {
          ElMessage({
            type: 'error',
            message: '提示，请完成最少3个坐标点的绘制。',
            duration: 5000
          })
        }
        isSetColor = false;
      } else {
        ElMessage({
          type: 'error',
          message: '提示，当前未产生新图形的路径绘制，无法完成保存操作，请完成最少3个坐标点的绘制。',
          duration: 5000
        })
      }
      currentStatus = true;
      isSubmit = true;
      isEdit = false;
      clearCurrent.value = false;
      isMapping.value = false;
    };

    const getPathData = (points: any) => {
      // 根据坐标点生成 SVG path 数据
      return points.reduce((data: any, point: any, index: any) => {
        const command = index === 0 ? 'M' : 'L';
        return `${data} ${command} ${point.x} ${point.y}`;
      }, '');
    };

    /*** 监听窗口的变化 */
    const listenerFun = async () => {
      const resizeObserver = new ResizeObserver(entries => {
        for (let entry of entries) {
          const { width, height } = entry.contentRect;
          // 计算舞台的缩放比例
          const scaleX = width / stageWidth;
          const scaleY = height / stageHeight;
          const newScale = Math.min(scaleX, scaleY);

          // 更新舞台的宽高和缩放比例
          stage.width(width);
          stage.height(height);
          stage.scale({ x: newScale, y: newScale });

          // 更新舞台宽高变量
          stageWidth = width;
          stageHeight = height;

          // 重新绘制舞台内容
          stage.batchDraw();
          if (backgroundImage && props.isUseDialog) {
            backgroundImage.width(width);
            backgroundImage.height(height);
            backgroundLayer.batchDraw(); // 重新绘制图层
            repaintCoord(); // 绘制坐标点
          }
        }
      });
      // 监听 konvaContainer 元素
      const konvaContainer: any = document.querySelector('#konvaContainer');
      resizeObserver.observe(konvaContainer);
    }

    /*** 设置背景图 */
    const setBjFun = () => {
      // 加载背景图片
      let imageObj = new Image();
      // 创建图片对象
      if (!backgroundImage) {
        backgroundImage = new Konva.Image({
          width: stage.width(), // 图片宽度与舞台宽度相同
          height: stage.height(), // 图片高度与舞台高度相同
          image: imageObj, // 图片对象
          draggable: false // 禁止拖拽
        });
        // 将图片对象添加到背景图层
        backgroundLayer.add(backgroundImage);
      }

      imageObj.onload = function () {
        backgroundImage.image(imageObj as CanvasImageSource);
        backgroundLayer.draw(); // 重新绘制图层
      };
      imageObj.src = imageBj; // 背景图片路径

      // 将背景图层添加到舞台
      stage.add(backgroundLayer);
    }

    /*** 设置舞台代码 */
    const StageFun = async () => {
      if (GetBool) {
        await listenerFun();
        // 创建 Konva 舞台
        stage = new Konva.Stage({
          container: konvaContainer.value,
          width: stageWidth,
          height: stageHeight,
        });
        setBjFun();
        stage.add(layer);

        // 将自定义图形添加到层
        layer.add(customShape);

        // 更新层
        layer.draw();

        // 监听鼠标点击事件（监听左键点击事件）
        stage.on('click', (e: any) => {
          if (isEdit) {
            ElMessage({
              type: 'error',
              message: '系统检测到您当前有未完成的功能操作，请先完成操作。',
              duration: 5000
            });
            return
          }
          if (e.evt.button === 0) {
            currentStatus = false;
            isSetColor = true;
            isSubmit = false;
            isMapping.value = true;
            isAnewConfig.value = true;
            pos = stage.getPointerPosition();
            // 更新图层
            layer.draw();
            // 添加用户点击的坐标点到数组
            userPoints.push({ x: pos.x, y: pos.y });
            clearCurrent.value = true;
            dragFun(false);
          }
        });


        // 右键调出功能区变量
        let customMenu: any = null;

        // 右键功能区的块
        let liStyle = "cursor: pointer; padding: 5px 0px;margin-bottom: 10px;list-style-type:none;font-size: 14px;border-bottom: 1px solid #CFD3DC";
        let setInner = `<ul style="padding: 10px 15px;margin:5px 0px;">
            <li onclick="saveImage()" style="${liStyle}">重绘区域</li>
            <li onclick="copyImageURL()" style="${liStyle}">配置气泡</li>
            <li onclick="openImageInNewTab()" style="${liStyle}">清除当前绘制区</li>
            <li onclick="clearNewTab()" style="${liStyle}">关闭菜单</li>
          </ul>`;

        // 功能区样式设置
        let styleSetting = {
          position: 'absolute',
          backgroundColor: 'rgba(0,0,0,0.6)',
          color: '#FFFFFF',
          padding: '0px',
          borderRadius: '4px',
          zIndex: '9999',
        };

        // 重新绘制当前区域的函数
        const redrawCurrentRegion = (regionIndex: number, points: any) => {
          uploadAreaArr = toRaw(points); // 保存更新区域
          // 移除当前区域的所有路径
          layer.find('.current-region-path').forEach((shape: any) => shape.remove());
          const indexToRemove = drawnRegions.value.findIndex((region: any) => region.index === regionIndex);
          if (indexToRemove !== -1) {
            // drawnRegions.value.splice(indexToRemove, 1);
            layer.find('.current-region-paths').forEach((shape: any) => shape.remove());
            drawnRegions.value.forEach((region: any) => {
              const path = new Konva.Path({
                data: getPathData(region.points),
                fill: region.color,
                stroke: 'rgba(255, 255, 255, 0.3)',
                strokeWidth: 0.5,
                name: 'current-region-paths',
              });
              layer.add(path);
            });
          }

          // 重新绘制路径
          const path = new Konva.Path({
            data: getPathData(points),
            // fill: globalColor,
            stroke: 'rgba(255, 255, 255, 0.3)',
            strokeWidth: 0.5,
            name: 'current-region-path',
          });

          // 将路径添加到层
          layer.add(path);

          // 更新层
          layer.draw();
        };

        // 右键功能菜单 ‘编辑’
        const editArea = (pointerPosition: any) => {
          if (currentStatus) {
            // 检查指针是否在绘制的区域内
            const clickedRegionIndex = drawnRegions.value.findIndex((region: any) => {
              return isPointInsidePolygon(pointerPosition, region.points);
            });
            // 如果单机的位置在区域的范围内则处理或捕获区域信息
            if (clickedRegionIndex !== -1) {
              clearInx = clickedRegionIndex;
              currentStatus = false;
              isSetColor = false;
              isEdit = true;
              clearCurrent.value = true;
              const clickedRegionData = drawnRegions.value[clickedRegionIndex];
              uploadAreaArr = clickedRegionData.points;
              // 在被点击的区域上添加拖拽处理逻辑
              clickedRegionData.points.forEach((point: any, pointIndex: any) => {
                const circle: any = new Konva.Circle({
                  x: point.x,
                  y: point.y,
                  radius: 6,
                  fill: 'rgba(255,255,255,0.5)',
                  stroke: 'rgba(255,0,0,0.3)',
                  strokeWidth: 0.7,
                  draggable: true,  // 允许拖拽
                  name: 'clear-draggable',
                });

                // 监听拖动事件
                circle.on('dragmove', () => {
                  // 更新被拖动点的坐标
                  const updatedCoordinates = {
                    x: circle.x(),
                    y: circle.y(),
                  };
                  // 更新区域坐标
                  clickedRegionData.points[pointIndex] = updatedCoordinates;
                  // 重新绘制当前区域
                  redrawCurrentRegion(clickedRegionData.index, clickedRegionData.points);
                });

                // 鼠标移入圆点创建提示元素
                circle.on('mouseover', () => {
                  const stage = circle.getStage();
                  if (stage) {
                    stage.container().style.cursor = 'pointer';

                    // 创建工具提示元素
                    const tooltip = document.createElement('div');
                    tooltip.className = 'tooltip';
                    tooltip.textContent = '可拖动';
                    tooltip.style.color = '#262727'; // 设置提示字体的颜色
                    tooltip.style.fontWeight = '600'; // 设置提示字体的粗细
                    tooltip.style.fontSize = '16px'; // 设置提示字体的大小

                    // 将工具提示放在圆旁边
                    const containerRect = stage.container().getBoundingClientRect();
                    const circlePosition = circle.getAbsolutePosition();
                    tooltip.style.position = 'absolute';
                    tooltip.style.top = `${circlePosition.y + containerRect.top - 60}px`;
                    tooltip.style.left = `${circlePosition.x + containerRect.left - 140}px`;

                    // 将工具提示追加到鼠标旁边
                    stage.container().appendChild(tooltip);

                    // 设置一个标志来跟踪工具提示是否显示
                    circle.tooltipDisplayed = true;
                  }
                });

                // 鼠标移除圆点清除创建的元素
                circle.on('mouseout', () => {
                  const stage = circle.getStage();
                  if (stage) {
                    stage.container().style.cursor = 'crosshair';
                    if (circle.tooltipDisplayed) {
                      const tooltip = stage.container().querySelector('.tooltip');
                      if (tooltip) {
                        tooltip.remove();
                        circle.tooltipDisplayed = false;
                      }
                    }
                  }
                });

                // 将拖拽点添加到层
                layer.add(circle);
              });
            } else {
              ElMessage({
                type: 'error',
                message: '检测到没有有效的绘制区域,请先完成基础区域绘制并保存绘制区域',
                duration: 5000
              });
            }
          } else {
            ElMessage({
              type: 'error',
              message: '请先完成基础区域绘制并保存绘制区域',
              duration: 5000
            });
          }
        };

        // 清除当前区域
        clearArea = (pointerPosition?: any) => {
          if (currentStatus) {
            let clickedRegionIndex: any;
            if (pointerPosition) {
              // 检查指针是否在绘制的区域内，findIndex()查找指定元素，如果没找到则返回-1
              clickedRegionIndex = drawnRegions.value.findIndex((region: any) => {
                return isPointInsidePolygon(pointerPosition, region.points);
              });
            } else {
              currentStatus = false;
              isEdit = false;
              clickedRegionIndex = clearInx;
            }
            if (clickedRegionIndex !== -1) {
              isMapping.value = false;
              const clickedRegionData = drawnRegions.value[clickedRegionIndex];
              const indexToRemove = drawnRegions.value.findIndex((region: any) => region.index === clickedRegionData.index);

              if (indexToRemove !== -1) {
                if (bubbleDataArray.value[indexToRemove] && bubbleDataArray.value[indexToRemove].index === drawnRegions.value[indexToRemove].index) {
                  bubbleDataArray.value.splice(indexToRemove, 1);
                  bubbleLayer.removeChildren(); // 清除所有气泡内容层
                  anewDrawBubble(); // 重新渲染气泡数据
                }

                drawnRegions.value.splice(indexToRemove, 1);
                layer.find('.current-region-paths').forEach((shape: any) => shape.remove()); // 清除所有区域
                layer.find('.clear-draggable').forEach((shape: any) => shape.remove()); // 清除所有区域
                // 重新绘制区域
                drawnRegions.value.forEach((region: any) => {
                  const path = new Konva.Path({
                    data: getPathData(region.points),
                    fill: region.color,
                    stroke: 'rgba(255,255,255,0.5)',
                    strokeWidth: 0.5,
                    name: 'current-region-paths',
                  });
                  layer.add(path);
                });
              }
            } else {
              ElMessage({
                type: 'error',
                message: '检测到没有有效的绘制区域,请先完成基础区域绘制并保存绘制区域',
                duration: 5000
              })
            }
          } else {
            ElMessage({
              type: 'error',
              message: '请先完成基础区域绘制并保存绘制区域',
              duration: 5000
            })
          }
        };

        // cancelFun 取消功能区函数
        const cancelFun = () => {
          customMenu.parentElement.removeChild(customMenu);
        };

        /*** 监听右键功能区设置 */
        stage.on('contextmenu', (e: any) => {
          e.evt.preventDefault(); // 阻止默认右键菜单

          // 移除先前的自定义菜单
          if (customMenu && customMenu.parentElement) {
            cancelFun();
          }

          // 右键获取当前坐标
          const pointerPosition = stage.getPointerPosition();
          rightCo = pointerPosition; // 设置右键坐标
          getX = Math.min(pointerPosition.x);
          getY = Math.min(pointerPosition.y);
          // 检查当前右键的坐标是否在绘制的区域内，如果在则判断区域是否为当前主记录的绘制区，如果是则调用菜单功能键，否则不禁止调用菜单功能
          const getPointer = drawnRegions.value.findIndex((region: any) => {
            return isPointInsidePolygon(rightCo, region.points);
          });
          if (getPointer !== -1) {
            let isFunBoolen = drawnRegions.value[getPointer].isMasterRecord;
            if (isFunBoolen === false) {
              ElMessage({
                type: 'error',
                message: '违规行为，操作区域不属于 “当前分区” ，请前往对应分区进行编辑。',
                duration: 5000
              })
            }
            if (isFunBoolen === true || isFunBoolen === undefined) {
              // 创建自定义菜单
              customMenu = document.createElement('div');
              customMenu.innerHTML = setInner;
              // 设置菜单样式
              Object.assign(customMenu.style, styleSetting);
              customMenu.style.left = e.evt.clientX + 'px';
              customMenu.style.top = e.evt.clientY + 'px';
              document.body.appendChild(customMenu); // 将菜单添加到页面
            }
          } else {
            ElMessage({
              type: 'error',
              message: '违规行为，未检测到鼠标在有效区域内。',
              duration: 5000
            })
          }

          // 在自定义菜单中添加相应的事件处理函数
          // 编辑功能
          window.saveImage = () => {
            // 实现重绘区域的逻辑
            isSubmit = false;
            editArea(pointerPosition);
          };

          // 添加气泡
          window.copyImageURL = () => {
            if (currentStatus) {
              // 检查指针是否在绘制的区域内
              const clickedRegionIndex = drawnRegions.value.findIndex((region: any) => {
                return isPointInsidePolygon(rightCo, region.points);
              });
              if (clickedRegionIndex === -1) {
                ElMessage({
                  type: 'error',
                  message: '请先完成基础区域绘制并保存绘制区域',
                  duration: 5000
                });
              } else {
                // 实现添加气泡的逻辑
                isAnewConfig.value = false;
                dialogVisible.value = true; // 显示设置文本框
              }
            } else {
              ElMessage({
                type: 'error',
                message: '请先完成基础区域绘制并保存绘制区域',
                duration: 5000
              })
            }
          };

          // 清除当前区域
          window.openImageInNewTab = () => {
            // 实现清除路径绘制的逻辑
            clearArea(pointerPosition);
          };

          /*** 取消功能区 */
          window.clearNewTab = () => {
            // 实现取消的逻辑
            if (document.body.contains(customMenu)) {
              cancelFun();
            }
          };

          // 在点击其他地方时，移除自定义菜单
          document.addEventListener('click', function () {
            if (document.body.contains(customMenu)) {
              cancelFun();
            }
          });

          // 阻止冒泡，以防止点击菜单时触发 document 的 click 事件
          e.evt.stopPropagation();
        });
      }
    };

    return {
      handleClose,
      submitForm,
      cancelUseClick,
      titleCon,
      isUseDialog,
      repeatDis,
      dialogVisible,
      cancelHtClick,
      confirmHtClick,
      saveCurrentRegion,
      clearDraw,
      returnStep,
      outBox,
      // container,
      konvaContainer,
      definitionColor,
      setColor,
      showOverlay,
      isMapping,
      countDownSec,
      clearCurrent,
      clearCurrentHandle,
      isAnewConfig,
    }
  },
})
</script>

<style scoped lang="scss">
#drawArea {
  width: 100%;
  height: 100%;

  .set-s {
    width: 100%;
    height: 100%;

    :deep(.el-dialog__body) {
      width: 100%;
      height: 100%;
      // height: calc(100vh - 110px);
      // max-height: none !important;
      // overflow-y: hidden;
    }
  }

  #konvaContainer {
    width: 110%;
    height: 120%;
    // cursor: crosshair;
    /* 鼠标变为十字形，提示用户可以点击绘制 */
  }
}
</style>